/* eslint-disable class-methods-use-this */
import { bindAll } from '@/utils/utils';
import DragPan from './DragPan';
import DragRotate from './DragRotate';
import EditView from '@/view/EditView';
import Inertia from './Inertia';

class HandlerManager {
  private _editView: EditView;
  private _dragPan: DragPan;
  private _dragRotate: DragRotate;
  private _inertia: Inertia = new Inertia();

  constructor(editView: EditView) {
    bindAll([
      '_onmousedown',
      '_onmousemove',
      '_onmouseup',
      '_onmouseleave',
    ], this);
    this._editView = editView;
    this._setup(this._editView.getContainer());

    this._dragPan = new DragPan(this);
    this._dragRotate = new DragRotate(this);
  }

  private _setup(container: HTMLElement) {
    container.addEventListener('mousedown', this._onmousedown);
    container.addEventListener('mousemove', this._onmousemove);
    container.addEventListener('mouseup', this._onmouseup);
    container.addEventListener('mouseleave', this._onmouseleave);
    container.addEventListener('contextmenu', HandlerManager.stopEvent);
  }

  destroy() {
    const container = this._editView.getContainer();
    container.removeEventListener('mousedown', this._onmousedown);
    container.removeEventListener('mousemove', this._onmousemove);
    container.removeEventListener('mouseup', this._onmouseup);
    container.removeEventListener('mouseleave', this._onmouseleave);
    container.removeEventListener('contextmenu', HandlerManager.stopEvent);
  }

  private _onmousedown(e: MouseEvent) {
    HandlerManager.stopEvent(e);
    this._dragPan.mousedown(e);
    this._dragRotate.mousedown(e);
  }

  private _onmousemove(e: MouseEvent) {
    HandlerManager.stopEvent(e);
    this._dragPan.mousemove(e);
    this._dragRotate.mousemove(e);
  }

  private _onmouseup(e: MouseEvent) {
    HandlerManager.stopEvent(e);
    this._dragPan.mouseup(e);
    this._dragRotate.mouseup(e);
  }

  private _onmouseleave(e: MouseEvent) {
    HandlerManager.stopEvent(e);
    this._dragPan.mouseleave(e);
    this._dragRotate.mouseleave(e);
  }

  getView() {
    return this._editView;
  }

  static stopEvent(e: MouseEvent | TouchEvent) {
    e.stopPropagation();
    e.preventDefault();
  }

  getInertia() {
    return this._inertia;
  }

  /**
   * 显示结尾惯性动画
   */
  inertiaEasing() {
    this._inertia.calculate();
  }
}

export default HandlerManager;
